package com.fingerth.crawler.utils.stati

import android.app.Activity
import android.content.*
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Path
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Looper
import android.provider.MediaStore
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.graphics.drawable.DrawableCompat
import androidx.viewpager.widget.ViewPager
import com.fingerth.crawler.R
import com.fingerth.xadapter.XViewHolder
import com.google.android.material.tabs.TabLayout
import com.google.gson.Gson
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList

fun String.showToast(context: Context?, duration: Int = Toast.LENGTH_SHORT) = Toast.makeText(context, this, duration).show()
fun String.tryToInt(def: Int = 0): Int {
    var p = def
    try {
        p = this.toInt()
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return p
}

fun String.tryToLong(def: Long = 0): Long {
    var p = def
    try {
        p = this.toLong()
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return p
}

/**
 * 特殊字符处理
 */
fun withSpecialCharacters(origin: String?): String {
    if (origin == null) return ""
    val map = mutableMapOf("&lt;" to "<", "&gt;" to ">", "&amp;" to "&", "&quot;" to "\"", "&copy;" to "©", "&yen;" to "¥", "&divide;" to "÷", "&times;" to "×", "&reg;" to "®", "&sect;" to "§", "&pound;" to "£", "&cent;" to "￠", "&nbsp;" to " ")
    var temp: String = origin
    map.forEach {
        temp = temp.replace(it.key.toRegex(), it.value)
    }
    return temp
}

/**
 * Path绘制
 */
fun Path.walk(vararg points: Pair<Float, Float>) {
    reset()
    repeat(points.count()) { if (it == 0) moveTo(points[it].first, points[it].second) else lineTo(points[it].first, points[it].second) }
    close()
}

infix fun View.click(block: () -> Unit) = setOnClickListener { block() }
infix fun Array<View>.click(block: () -> Unit) = this.forEach { it.setOnClickListener { block() } }
infix fun TabLayout.setup(vp: ViewPager) = setupWithViewPager(vp)
infix fun Window.alpha(a: Float) = run { this.attributes = this.attributes.apply { alpha = a } }
fun ViewGroup.inflate(@LayoutRes layout: Int, attachToRoot: Boolean = true): View = LayoutInflater.from(context).inflate(layout, this, attachToRoot)
fun XViewHolder.at(vararg pairs: Pair<Int, String?>) = pairs.forEach { setText(it.first, it.second ?: "") }


fun SharedPreferences.put(block: SharedPreferences.Editor.() -> Unit) {
    val editor = edit()
    editor.block()
    editor.apply()
}

private var <T : View>T.triggerLastTime: Long
    get() = if (getTag(R.id.triggerLastTimeKey) != null) getTag(R.id.triggerLastTimeKey) as Long else 0
    set(value) {
        setTag(R.id.triggerLastTimeKey, value)
    }


private var <T : View> T.triggerDelay: Long
    get() = if (getTag(R.id.triggerDelayKey) != null) getTag(R.id.triggerDelayKey) as Long else -1
    set(value) {
        setTag(R.id.triggerDelayKey, value)
    }

private fun <T : View> T.clickEnable(): Boolean {
    var clickable = false
    val currentClickTime = System.currentTimeMillis()
    if (currentClickTime - triggerLastTime >= triggerDelay) {
        clickable = true
    }
    triggerLastTime = currentClickTime
    return clickable
}

fun <T : View> T.clickWithTrigger(delay: Long = 800, block: (T) -> Unit) {
    triggerDelay = delay
    setOnClickListener {
        if (clickEnable()) {
            block(this)
        }
    }
}


//switch
fun px2dp(context: Context?, pxValue: Float): Int = (px2dpFloat(context, pxValue) + 0.5f).toInt()
fun dp2px(context: Context?, dpValue: Float): Int = context?.let { (dpValue * it.resources.displayMetrics.density + 0.5f).toInt() } ?: 0
fun px2dpFloat(context: Context?, pxValue: Float): Float = context?.let { pxValue / it.resources.displayMetrics.density } ?: 0f
fun px2sp(context: Context?, pxValue: Float): Int = context?.let { (pxValue / it.resources.displayMetrics.scaledDensity + 0.5f).toInt() } ?: 0
fun sp2px(context: Context?, spValue: Float): Int = context?.let { (spValue * it.resources.displayMetrics.scaledDensity + 0.5f).toInt() } ?: 0

inline fun <reified T> json2obj(jsonStr: String?): T? {
    var t: T? = null
    try {
        t = Gson().fromJson(jsonStr, T::class.java)
        // Gson().fromJson(it, object : TypeToken<ArrayList<RecommendBean>>() {}.type)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return t
}

fun obj2json(any: Any?): String {
    var jsonStr: String = ""
    try {
        jsonStr = Gson().toJson(any)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return jsonStr
}

//format
fun formatData(date: Date): String = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()).format(date)
fun formatDate2(date: Date): String = SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(date)//20200106
fun formatDate3(date: Date): String = SimpleDateFormat("yyyyMMddHHmm", Locale.getDefault()).format(date)//20200106

//获取系统时间
fun getSystemTime(): String = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date(System.currentTimeMillis()))

fun long2date1(l: Long): String = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(l * 1000L))

//UI
inline fun <reified T : Activity> ktStartActivity(context: Context?) {
    val intent = Intent(context, T::class.java)
    context?.startActivity(intent)
}

inline fun <reified T : Activity> ktStartActivity(context: Context?, block: Intent.() -> Unit) {
    val intent = Intent(context, T::class.java)
    intent.block()
    context?.startActivity(intent)
}

fun getChannelId(context: Context?, defChannelId: String = "1000"): String {
    context?.let {
        return try {
            val channelId = it.packageManager.getApplicationInfo(it.packageName, PackageManager.GET_META_DATA).metaData["QD_CHANNEL_ID"]
            if (channelId.toString().isEmpty()) defChannelId else channelId.toString()
        } catch (e: Exception) {
            e.printStackTrace()
            defChannelId
        }
    } ?: return defChannelId
}


fun startPhotoZoom(activity: Activity?, code: Int, uri: Uri?, outputX: Int = 400, outputY: Int = 400, tempFile: File) {
    val x = S.getSysWidth(activity)
    val y = x * outputY / outputX
    val intent = Intent("com.android.camera.action.CROP").apply {
        setDataAndType(uri, "image/*")
        // crop为true是设置在开启的intent中设置显示的view可以剪裁
        putExtra("crop", "true")
        // aspectX aspectY 是宽高的比例
        putExtra("aspectX", x)
        putExtra("aspectY", y)
        // outputX,outputY 是剪裁图片的宽高
        putExtra("outputX", outputX)
        putExtra("outputY", outputY)
        putExtra("scale", true) //是否保存比例
        putExtra("return-data", false) //剪裁是否返回bitmap
        putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile))
        putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString())
    }
    activity?.startActivityForResult(intent, code)
}


fun isMainThread(): Boolean {
    return Looper.getMainLooper().thread == Thread.currentThread()
}

fun copyText(context: Context, str: String?) {
    val cm = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    cm.setPrimaryClip(ClipData.newPlainText(null, str))
}

fun getDateAfter(d: Date, day: Int): Date = Calendar.getInstance().run {
    time = d
    set(Calendar.DATE, get(Calendar.DATE) + day)
    time
}

fun hideKeyboard(act: Activity) {
    val imm: InputMethodManager = act.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    // 隐藏软键盘
    imm.hideSoftInputFromWindow(act.window.decorView.windowToken, 0)
}

fun showKeyboard(et: EditText, act: Activity) {
    et.requestFocus()
    val imm: InputMethodManager = act.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT)
}

fun hideKeyboard(vararg et: EditText) {
    var focusEt = et[0]
    for (e in et) {
        if (e.isFocused) {
            focusEt = e
        }
    }
    val imm: InputMethodManager = focusEt.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    // 隐藏软键盘
    imm.hideSoftInputFromWindow(focusEt.windowToken, 0)
}

fun hideTheKeyboard(act: Activity?) {
    act?.window?.let {
        if (it.attributes.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            //隐藏软键盘
            it.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
            it.attributes.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
        }
    }
}


fun formatAddressStr(province: String?, city: String?): String {
    var address = ""
    if (!province.isNullOrBlank()) address = province
    if (!city.isNullOrBlank() && address != city) address += "-$city"

    return address
}

fun <T> eqx(e: List<T>, q: List<T>): List<Int> {
    val l = ArrayList<Int>()
    for ((index, i) in e.withIndex()) {
        if (q.size > index && i != q[index]) {
            l.add(index)
        }
    }
    return l
}

fun iconC(context: Context, res: Int, c: Int): Drawable? {
    val icon: Drawable? = AppCompatResources.getDrawable(context, res)
    icon?.let {
        DrawableCompat.setTint(icon, c)
    }
    return icon
}

